/**
 * Filter Contigs Query
 * Filter Contig Pairs 
 */
package jpave.query_interface;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JSeparator;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JScrollPane;
import javax.swing.border.Border;
import javax.swing.border.CompoundBorder;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.Iterator;
import java.util.Vector;

import util.Debug.ErrorReport;
import util.methods.Converters;
import util.ui.CollapsiblePanel;
import util.ui.MenuTreeNode;
import util.ui.ToggleTextComboField;
import util.ui.ToggleTextField;
import util.ui.UserPrompt;

import jpave.dataholders.FilterContigData;
import jpave.dataholders.QueryData;
import jpave.dataholders.SessionData;
import jpave.manager.ManagerFrame;

public class QueryTab extends Tab 
{
	private static final boolean debug = false;
	private JPaveFrame tcwFrame;
	
	public QueryTab ( JPaveFrame inFrame, QueryData inQuery ) throws Exception
	{
		super(inFrame, null); 
		tcwFrame = inFrame;
		theAssemblies = inFrame.getAssemblyList ();
		JLabel test = new JLabel ( "99999999" );
		defaultLabelDims = test.getPreferredSize();
		test = new JLabel ("99999");
		defaultLabelNumDims = test.getPreferredSize();
		
		theQuery = inQuery;
		tempContigFilter = (FilterContigData) Converters.deepCopy( theQuery.getContigFilter() );
	}
	/**
	 * called from JPaveFrame on openAssembly (startup). 
	 * create right pane for contig and pairs filter
	 */
	public void setupDialog ( 	MenuTreeNode contigNode,
								MenuTreeNode pairNode)
	{
		this.contigNode = contigNode;
		this.pairNode = pairNode;

		// Filter Contig Query sections
		contigNode.addChild(new MenuTreeNode(GENERAL_HEADER,	this));
		if(getParentFrame().hasExpLevels()) 
			contigNode.addChild(new MenuTreeNode(LIBRARY_HEADER, 	this));
		contigNode.addChild(new MenuTreeNode(BEST_DB_HIT_HEADER, this));
		contigNode.addChild(new MenuTreeNode(SNP_ORF_HEADER, this));
		contigNode.addChild(new MenuTreeNode(PVAL_HEADER, this));
		
		// Filter Pairs Query sections
		pairNode.addChild(new MenuTreeNode("Similarity", this));

		JTextField test = new JTextField ( "WHAAA???" );
		MIN_ROW_HEIGHT = (int)test.getPreferredSize().getHeight() + 5;
		
		lblTitle = new JLabel();
		txtDesc = new JTextArea();
		Font f = lblTitle.getFont();
		lblTitle.setFont(new Font(f.getName(), f.getStyle(), f.getSize()+4));
		txtDesc.setFont(new Font(f.getName(), Font.PLAIN, f.getSize()));
		txtDesc.setAlignmentX(Component.LEFT_ALIGNMENT);
		txtDesc.setEditable(false);
		
		lblError.setText( " " );
		lblError.setVisible(false);
		
		JButton btnExpandAll = new JButton("Expand All");
		btnExpandAll.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent event) {
				zoomAll(true);
			}
		});
		
		JButton btnCollapseAll = new JButton("Collapse All");
		btnCollapseAll.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent event) {
				zoomAll(false);
			}
		});
		
		JButton btnHelp = new JButton("Help");
		btnHelp.setBackground(ManagerFrame.HELPCOLOR);
		btnHelp.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				UserPrompt.displayHTMLResourceHelp(getParentFrame(), "Filter Query", "html/viewSingleTCW/QueryTab.html");
			}
		});

		JPanel buttonPanel = new JPanel();
		buttonPanel.setLayout(new BoxLayout ( buttonPanel, BoxLayout.X_AXIS ));
		buttonPanel.setBackground(Color.WHITE);
		buttonPanel.add(btnExpandAll);
		buttonPanel.add(Box.createHorizontalStrut(5));
		buttonPanel.add(btnCollapseAll);
		buttonPanel.add(Box.createHorizontalStrut(5));
		buttonPanel.add(btnHelp);
		buttonPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
		buttonPanel.setMaximumSize(buttonPanel.getPreferredSize());
		
		centerPanel = new JPanel();
		centerPanel.setLayout(new BoxLayout ( centerPanel, BoxLayout.Y_AXIS ));
		centerPanel.setBorder( BorderFactory.createEmptyBorder(10, 10, 10, 10) );
		centerPanel.setBackground(Color.WHITE);
		centerPanel.add( buttonPanel );
		centerPanel.add( Box.createVerticalStrut(20) );
		centerPanel.add( lblTitle );
		centerPanel.add( txtDesc );
		centerPanel.add( Box.createVerticalStrut(15) );
		
		// Contig
		loadContigSetColumns();
		loadPValColumns();
		centerPanel.add( contigPanel 	= createContigFilter ( tempContigFilter ) );
		if(getParentFrame().hasExpLevels()) 
			centerPanel.add( selLibraryPanel    = createSelectLibrary( tempContigFilter));
		if(( PValPanel = createSelectPVal(tempContigFilter)) != null)
			centerPanel.add( PValPanel );
		centerPanel.add( uniprotPanel 	= createDBidFilters ( tempContigFilter ) );
	
		if(( GOPanel 	= createGOFilters ( tempContigFilter ) ) != null)
			centerPanel.add( GOPanel ); 
		if(( SNPandORFPanel 	= createCodingRegionFilters ( tempContigFilter ) ) != null)
			centerPanel.add( SNPandORFPanel );
		
		// Pairwise
		centerPanel.add( similarityPanel 	= createPairsFilters( tempContigFilter ) );
		centerPanel.add( Box.createVerticalGlue() );
		
		scroller = new JScrollPane ( centerPanel);
		scroller.setBorder( null );
		scroller.setPreferredSize(getParentFrame().getSize());
		scroller.getVerticalScrollBar().setUnitIncrement(15);
		
		removeAll();
		setLayout( new BoxLayout ( this, BoxLayout.Y_AXIS ));
		add( lblError );
		add( scroller );
		
		if(getParentFrame().hasExpLevels()) 
			updateLibSelectStatus();
	}
	
	public void executeQuery ( boolean contigQuery ) 
	{	
		// Validate the UI settings
		if ( !doDataValidation() )
			return;

		// Load the settings from the UI into the query object
		try {
			getUISettings(theQuery);
		} catch (DataValidationError err) {
			ErrorReport.reportError(err, "Internal error: executeQuery");
		}
		
		if(contigQuery)
			theQuery.setType(QueryData.QUERY_CONTIGS);
		else
			theQuery.setType(QueryData.QUERY_PAIRS);
				
		// Pass the query onto the frame for execution
		++nChildren;
		getParentFrame().addQueryResultsTab ( theQuery, "Filter" + nChildren ); 
	}

	//Loads contigIDs to table
	public void executeQuery ( String tag, String [] contigIDs, int viewMode ) 
	{	
		if ( !doDataValidation() )
			return;

		try {
			getUISettings(theQuery);
		} catch (DataValidationError err) {
			// This shouldn't be possible; just to make java happy...
			ErrorReport.reportError(err, "Internal error: executeQuery");
		}
		
		theQuery.setType(QueryData.QUERY_CONTIGS);
		
		++nChildren;
		if (tag==null) tag = "List" + nChildren;
		getParentFrame().addQueryResultsTab ( theQuery, contigIDs, viewMode, tag); 
	}

	private void getUISettings ( QueryData outQuery ) throws DataValidationError 
	{
		getContigInputFromUI ( tempContigFilter );
		outQuery.setContigFilter ( tempContigFilter );
		getPairsInputFromUI ( outQuery ); 
	}
	
	// get user input values from "Filter Pairs Query"
	private void getPairsInputFromUI ( QueryData outQuery ) throws DataValidationError 
	{		
		//mrw: modified to set default values if similarity not selected.
		int ntHSRLen, aaHSRLen;
		double ntHSRPerLen, aaHSRPerLen;
		int ntOLPLen, aaOLPLen;
		double ntOLPPerLen, aaOLPPerLen;
		double AAOLPPerID, NTOLPPerID, AAHSRPerID, NTHSRPerID;
		if(chkPairsCutoffs.isSelected())
		{
			ntHSRLen = 	getAndValidateInteger ( fldPairsHSRMinNTLen );
			ntHSRPerLen = 	getAndValidatePercent ( fldPairsHSRMinNTPercentLen ); 
			aaHSRLen = 	getAndValidateInteger( fldPairsHSRMinAALen );
			aaHSRPerLen = 	getAndValidatePercent ( fldPairsHSRMinAAPercentLen ); 

			ntOLPLen = 	getAndValidateInteger ( fldPairsOLPMinNTLen );
			ntOLPPerLen = 	getAndValidatePercent ( fldPairsOLPMinNTPercentLen ); 
			aaOLPLen = 	getAndValidateInteger( fldPairsOLPMinAALen );
			aaOLPPerLen = 	getAndValidatePercent ( fldPairsOLPMinAAPercentLen ); 
			
			AAOLPPerID = 	getAndValidatePercent ( fldPairsOLPMinAAPercentID ); 
			NTOLPPerID = 	getAndValidatePercent ( fldPairsOLPMinNTPercentID ); 
			AAHSRPerID = 	getAndValidatePercent ( fldPairsHSRMinAAPercentID ); 
			NTHSRPerID = 	getAndValidatePercent ( fldPairsHSRMinNTPercentID ); 
		}
		else
		{
			ntHSRLen = aaHSRLen = ntOLPLen = aaOLPLen = 0;
			ntHSRPerLen = aaHSRPerLen = ntOLPPerLen = aaOLPPerLen = 0.0;
			AAOLPPerID = NTOLPPerID = AAHSRPerID = NTHSRPerID = 0.0;
		}
		
		outQuery.setPairsCompareSimilarity( chkPairsCutoffs.isSelected() );
		outQuery.setPairsCompareBestHit( chkPairsCompareBestHit.isSelected() );
		outQuery.setPairsHSRMinNTLen( ntHSRLen );
		outQuery.setPairsHSRMinNTPercentLen( ntHSRPerLen );
		outQuery.setPairsHSRMinAALen( aaHSRLen );
		outQuery.setPairsHSRMinAAPercentLen( aaHSRPerLen );		
		outQuery.setPairsOLPMinNTLen( ntOLPLen );
		outQuery.setPairsOLPMinNTPercentLen( ntOLPPerLen );
		outQuery.setPairsOLPMinAALen( aaOLPLen );
		outQuery.setPairsOLPMinAAPercentLen( aaOLPPerLen );		
		outQuery.setPairsOLPMinAAPercentID( AAOLPPerID );		
		outQuery.setPairsOLPMinNTPercentID( NTOLPPerID );		
		outQuery.setPairsHSRMinAAPercentID( AAHSRPerID );		
		outQuery.setPairsHSRMinNTPercentID( NTHSRPerID );		
	}
	
	// get user input values from "Filter Contig Query"
	private void getContigInputFromUI ( FilterContigData outFilter ) throws DataValidationError 
	{		
		int nDBHitLen = 0;
		if(chkDBHitLen.isSelected())
			nDBHitLen = getAndValidateInteger ( chkDBHitLen );
		
		int nDBHitBitScore = 0;
		if(chkDBHitBitScore.isSelected())
			nDBHitBitScore = getAndValidateInteger ( chkDBHitBitScore );
		
		double dDBHitEVal = getAndValidateDouble ( chkDBHitEVal );
		int nDBHitIdent = 0;
		if(SNPandORFPanel != null && chkDBHitIdent != null && chkDBHitIdent.isSelected())
			nDBHitIdent = getAndValidateInteger ( chkDBHitIdent );

		int nNumAlign = 0;
		if (tcwFrame.hasAssembly() && chkNumAligns.isSelected()) {
		     nNumAlign = getAndValidateInteger( chkNumAligns );
		}
		int nCtgLen = 0;
		if(chkCtgLength.isSelected())
			nCtgLen = getAndValidateInteger( chkCtgLength );
		
		int nTotalExpLevel = 0;
		if(getParentFrame().hasExpLevels() && chkTotalExpLevel.isSelected())
			nTotalExpLevel = getAndValidateInteger( chkTotalExpLevel );
				
		int nMinSNPs = 0;	
		int nMaxSNPs = 0;		
		int nORFMinNT = 0;
		if(SNPandORFPanel != null) {
			if (tcwFrame.hasAssembly()) {
				nMinSNPs = getAndValidateInteger( chkGreaterEqualSNPs );	
				nMaxSNPs = getAndValidateInteger( chkLessEqualSNPs );
			}
			nORFMinNT = getAndValidateInteger( chkHasORF );	
		}
		
		if(PValPanel != null) {
			if(getSelectedPValColumns().length == 0 && chkFilterPVal.isSelected())
				throw new DataValidationError ( chkFilterPVal, "Please select at least one DE p-value" );
			outFilter.setSelectedPValColumns(getSelectedPValColumns(), 
						getSelectedUpColumns(), getSelectedDownColumns());
			outFilter.setPValBoolAND(cmbBoolPVal.getSelectedIndex() == 0);
			outFilter.setPValFilter(chkFilterPVal.isSelected());
			
			try {
				if(chkFilterPVal.isSelected())
					outFilter.setPValLimit(Double.parseDouble(txtPVal.getText()));
			}
			catch(NumberFormatException e) {
				throw new DataValidationError ( chkFilterPVal, "Invalid value for DE p-value limit" );
			}
		}
		
		// Contig attributes
		if(getParentFrame().hasExpLevels()) {
			outFilter.setIncludeLibs(getSelectedIncludeLibs());
			outFilter.setExcludeLibs(getSelectedExcludeLibs());
			
			if(incLibraryCountPromptField.isSelected() && getNumSelectedIncludeLibs() == 0)
				throw new DataValidationError ( incLibraryCountPromptField, "Please select at least one include library" );
			outFilter.setNumIncLibrary(incLibraryCountPromptField.isSelected() && getNumSelectedIncludeLibs() > 0);
			
			if(exLibraryCountPromptField.isSelected() && getNumSelectedExcludeLibs() == 0)
				throw new DataValidationError ( exLibraryCountPromptField, "Please select at least one exclude library" );
			outFilter.setNumExLibrary(exLibraryCountPromptField.isSelected() && getNumSelectedExcludeLibs() > 0);
			
			if(libraryComparePromptField.isSelected() && getNumSelectedIncludeLibs() == 0)
				throw new DataValidationError ( libraryComparePromptField, "Please select at least one include library" );
			if(libraryComparePromptField.isSelected() && getNumSelectedExcludeLibs() == 0)
				throw new DataValidationError ( libraryComparePromptField, "Please select at least one exclude library" );
			
			outFilter.setNFoldLibrary(libraryComparePromptField.isSelected() && getNumSelectedIncludeLibs() > 0 && getNumSelectedExcludeLibs() > 0);
			
			outFilter.setLibNormalized(chkNormalizedLibraryCounts.isSelected());
			
			outFilter.setIncLibsCountAnd(incLibraryCountPromptField.getOption2() == 0);
			outFilter.setExLibsCountAnd(exLibraryCountPromptField.getOption2() == 0);
			outFilter.setNFoldIncAnd(libraryComparePromptField.getOption2() == 0);
			outFilter.setNFoldExAnd(libraryComparePromptField.getOption3() == 0);
			
			if(incLibraryCountPromptField.getNum() <= 0 && incLibraryCountPromptField.isSelected())
				throw new DataValidationError ( incLibraryCountPromptField, "Please enter a valid value for included counts");				
			outFilter.setIncLibsCount(incLibraryCountPromptField.getNum());

			//For exclude, 0 is a valid value
			if(exLibraryCountPromptField.getNum() < 0 && exLibraryCountPromptField.isSelected())
				throw new DataValidationError ( exLibraryCountPromptField, "Please enter a valid value for excluded counts");
			outFilter.setExLibsCount(exLibraryCountPromptField.getNum());

			if(libraryComparePromptField.getNum() <= 0 && libraryComparePromptField.isSelected())
				throw new DataValidationError ( libraryComparePromptField, "Please enter a valid value for N-Fold");
			outFilter.setNFoldLibs(libraryComparePromptField.getNum());
			
			outFilter.setFoldRange(libraryComparePromptField.getOption1());
		}	
		if (tcwFrame.hasAssembly()) {
			outFilter.setCtgNumAligns( chkNumAligns.isSelected() );
			outFilter.setCtgNumAlignsLT( chkNumAligns.getOptionSelection() == 0 );
			outFilter.setCtgNumAligns( nNumAlign );
		}
		
		outFilter.setCtgLength( chkCtgLength.isSelected() );
		outFilter.setCtgLengthLT( chkCtgLength.getOptionSelection() == 0 );
		outFilter.setCtgLength( nCtgLen );
		
		if(getParentFrame().hasExpLevels()) {
			outFilter.setCtgTotalExpLevel( chkTotalExpLevel.isSelected() );
			outFilter.setCtgTotalExpLevelLT( chkTotalExpLevel.getOptionSelection() == 0 );
			outFilter.setCtgTotalExpLevel( nTotalExpLevel );
		}
		
		if(SNPandORFPanel != null && tcwFrame.hasAssembly()) {
			outFilter.setGtrEquSNPs( chkGreaterEqualSNPs.isSelected () );	
			outFilter.setGtrEquSNPs( nMinSNPs );							
			outFilter.setLessEquSNPs( chkLessEqualSNPs.isSelected () );		
			outFilter.setLessEquSNPs( nMaxSNPs );							
		}		
		if(getParentFrame().hasNs())
			outFilter.setFilterHasNs( cmbIncludeExcludeNs.getValue() );	
		outFilter.setFilterHasNotes( cmbIncludeExcludeNotes.getValue() );
			
		// SNPs and ORFs filter
		if(SNPandORFPanel != null) {
			outFilter.setBothUTRs( chkHasBothUTRs.isSelected() );
			outFilter.setORFCoding( chkHasORF.isSelected() );	
			outFilter.setProteinORF( chkHasProteinORF.isSelected());
			outFilter.setORFMinNT( nORFMinNT );	
		}
		
		if(GOPanel != null) {
			outFilter.setGOID(chkGOID.isSelected());
			outFilter.setGOID(chkGOID.getText());
		}
		
		// UniProt filter
		outFilter.setDBHitAndOr( cmbDBHitAndOr.getValue());
		outFilter.setFirstBestSelected(cmbFirstBest.getValue()==0);
		
		outFilter.setDBHitLen( chkDBHitLen.isSelected() );	
		outFilter.setDBHitLen( nDBHitLen ); 
		outFilter.setDBHitLenLT(chkDBHitLen.getOptionSelection()==0);
		
		outFilter.setDBHitBitScore( chkDBHitBitScore.isSelected() );	
		outFilter.setDBHitBitScore( nDBHitBitScore );
		outFilter.setDBHitBestScoreLT(chkDBHitBitScore.getOptionSelection()==0);
		
		outFilter.setDBHitEval( chkDBHitEVal.isSelected() );
		outFilter.setDBHitEval( dDBHitEVal );
		outFilter.setDBHitEvalLT(chkDBHitEVal.getOptionSelection()==0);
		
		outFilter.setDBHitIdentity(chkDBHitIdent.isSelected());
		outFilter.setDBHitIdentity(nDBHitIdent);
		outFilter.setDBHitIdentityLT(chkDBHitIdent.getOptionSelection()==0);
		
		outFilter.setHasAnnotation(chkHasBestDBHit.isSelected());
		
		if(chkNoAnno != null)
			outFilter.setNoAnnotation(chkNoAnno.isSelected());
		
		if(chkEitherAnno != null) 
			outFilter.setEitherAnnotation(chkEitherAnno.isSelected());
		
		if(chkAnnoDB != null) {
			outFilter.setAnnoTaxoDB(getSelectedAnnoDBTaxos());
			outFilter.setAnnoTypeDB(getSelectedAnnoDBTypes());
		}
	}

	// called for Restore_defaults and Copy To Query ?
	public void setUIFromFilter(QueryData inQuery) {
		FilterContigData inFilter = inQuery.getContigFilter();
		
		if(inFilter.isLibNormalized())
			chkNormalizedLibraryCounts.setSelected(true);
		else
			chkAbsoluteLibraryCounts.setSelected(true);
		
		incLibraryCountPromptField.setSelected(inFilter.isNumIncLibrary());
		exLibraryCountPromptField.setSelected(inFilter.isNumExLibrary());
		libraryComparePromptField.setSelected(inFilter.isNFoldLibrary());

		incLibraryCountPromptField.setOption2(inFilter.isIncLibsCountAnd()?1:0);
		exLibraryCountPromptField.setOption2(inFilter.isExLibsCountAnd()?1:0);
		libraryComparePromptField.setOption2(inFilter.isNFoldIncAnd()?1:0);
		libraryComparePromptField.setOption3(inFilter.isNFoldExAnd()?1:0);

		incLibraryCountPromptField.setNum(inFilter.getIncLibsCount());
		exLibraryCountPromptField.setNum(inFilter.getExLibsCount());
		libraryComparePromptField.setNum(inFilter.getNFoldLibs());

		libraryComparePromptField.setOption1(inFilter.getFoldRange());
		
		if(getParentFrame().hasNs()) {
			cmbIncludeExcludeNs.setValue( inFilter.getFilterHasNs() );
		}
		cmbIncludeExcludeNotes.setValue( inFilter.getFilterHasNotes() );
		
		if (tcwFrame.hasAssembly()) {
			chkNumAligns.setSelected( inFilter.isCtgNumAligns() );
			chkNumAligns.setOptionSelection( inFilter.isCtgNumAlignsLT()?0:1 );
			chkNumAligns.setText( "" + inFilter.getCtgNumAligns() );
		}

		if(PValPanel != null) {
			txtPVal.setText(inFilter.getPValLimit() + "");
			chkFilterPVal.setSelected(inFilter.isPValFilter());
			cmbBoolPVal.setSelectedIndex(inFilter.isPValBoolAND()?1:0);
			
			String [] selectedVals = inFilter.getSelectedPValColumns();
			boolean upCols[] = inFilter.getPValUpColumns();
			boolean downCols[] = inFilter.getPValDownColumns();
			for(int x=0; x<colSelectPVal.length; x++) {
				colSelectPVal[x].setSelected(false);
				colUpDown[x].setSelected(true);
				if (selectedVals != null) { 
					for(int y=0; y<selectedVals.length; y++) {
						if(colSelectPVal[x].getText().equals(selectedVals[y])) {
							colSelectPVal[x].setSelected(true);
							if (upCols[y]) colUpOnly[x].setSelected(true);
							else if (downCols[y]) colDownOnly[x].setSelected(true);
						}
					}
				}
			}
		}

		chkCtgLength.setSelected( inFilter.isCtgLength() );
		chkCtgLength.setOptionSelection( inFilter.isCtgLengthLT()?0:1 );
		chkCtgLength.setText( "" + inFilter.getCtgLength() );
		
		if(getParentFrame().hasExpLevels()) {
			chkTotalExpLevel.setSelected( inFilter.isCtgTotalExpLevel() );
			chkTotalExpLevel.setOptionSelection( inFilter.isCtgLengthLT()?0:1 );
			chkTotalExpLevel.setText( "" + inFilter.getCtgTotalExpLevel() );
		}
		
		if (tcwFrame.hasAssembly()) {
			chkGreaterEqualSNPs.setSelected( inFilter.isGtrEquSNPs() );
			chkGreaterEqualSNPs.setText( ""+inFilter.getGtrEquSNPs() );
			
			chkLessEqualSNPs.setSelected( inFilter.isLessEquSNPs() );
			chkLessEqualSNPs.setText( ""+inFilter.getLessEquSNPs() );
		}
		// Coding Region
		if (chkHasORF != null)
		{
			chkHasORF.setSelected( inFilter.isORFCoding() );
			chkHasORF.setText( ""+inFilter.getORFMinNT() );
		}
		if (chkHasProteinORF != null) 
			chkHasProteinORF.setSelected( inFilter.isProteinORF() );
		if(chkHasBothUTRs != null) 
			chkHasBothUTRs.setSelected( inFilter.isBothUTRs() );
		
		
		//GO
		if(chkGOID != null) {
			chkGOID.setSelected(inFilter.isGOID());
			chkGOID.setText(inFilter.getGOID());
		}
		
		// UniProt Hit
		
		cmbFirstBest.setValue(inFilter.isFirstBestSelected()?1:0);
		cmbDBHitAndOr.setValue( inFilter.getDBHitAndOr() );
		
		chkDBHitLen.setSelected( inFilter.isDBHitLen() );
		chkDBHitLen.setText( ""+inFilter.getDBHitLen());
		chkDBHitLen.setOptionSelection( inFilter.isDBHitLenLT()?0:1);
		
		chkDBHitBitScore.setSelected( inFilter.isDBHitBitScore() );
		chkDBHitBitScore.setText( ""+inFilter.getDBHitBitScore() );
		chkDBHitBitScore.setOptionSelection( inFilter.isDBHitBitScoreLT()?0:1);
		
		chkDBHitEVal.setSelected( inFilter.isDBHitEval() );
		chkDBHitEVal.setText("" + inFilter.getDBHitEval());
		chkDBHitEVal.setOptionSelection(inFilter.isDBHitEvalLT()?0:1);
		
		chkDBHitIdent.setSelected( inFilter.isDBHitIdentity());
		chkDBHitIdent.setText("" + inFilter.getDBHitIdentity());
		chkDBHitIdent.setOptionSelection(inFilter.isDBHitIdentityLT()?0:1);
		
		chkHasBestDBHit.setSelected(inFilter.hasAnnotation());
		if(chkNoAnno != null)
			chkNoAnno.setSelected(inFilter.hasNoAnnotation());
		if(chkEitherAnno != null)
			chkEitherAnno.setSelected(inFilter.hasEitherAnnotation());

		// Pairs
		chkPairsCutoffs.setSelected( inQuery.isPairsCompareSimilarity() );
		chkPairsCompareBestHit.setSelected( inQuery.isPairsCompareBestHit() );
		
		fldPairsHSRMinNTLen.setText( ""+inQuery.getPairsHSRMinNTLen()*100 );
		fldPairsHSRMinNTPercentLen.setText( ""+inQuery.getPairsHSRMinNTPercentLen() );
		fldPairsHSRMinAALen.setText( ""+inQuery.getPairsHSRMinAALen()*100 );
		fldPairsHSRMinAAPercentLen.setText( ""+inQuery.getPairsHSRMinAAPercentLen() );		

		fldPairsOLPMinNTLen.setText( ""+inQuery.getPairsOLPMinNTLen()*100 );
		fldPairsOLPMinNTPercentLen.setText( ""+inQuery.getPairsOLPMinNTPercentLen() );
		fldPairsOLPMinAALen.setText( ""+inQuery.getPairsOLPMinAALen()*100 );
		fldPairsOLPMinAAPercentLen.setText( ""+inQuery.getPairsOLPMinAAPercentLen() );		

		fldPairsOLPMinAAPercentID.setText( ""+inQuery.getPairsOLPMinAAPercentID() );		
		fldPairsOLPMinNTPercentID.setText( ""+inQuery.getPairsOLPMinNTPercentID() );		
		fldPairsHSRMinAAPercentID.setText( ""+inQuery.getPairsHSRMinAAPercentID() );		
		fldPairsHSRMinNTPercentID.setText( ""+inQuery.getPairsHSRMinNTPercentID() );		
	}

	// Called from JPaveFrame whenever in event in the menu occurs (was called zoom)
	public void filterWindow(MenuTreeNode node) {
		MenuTreeNode father = node.getParentNode();
		MenuTreeNode grandfather = father.getParentNode();
		
		if (node == contigNode || node == pairNode)
			setView(node);
		else if (father == contigNode || father == pairNode)
			setView(father);
		else if (grandfather == contigNode || grandfather == pairNode) 
		{
			setView(grandfather);
			node = father;
		}
		
		Component[] comps = centerPanel.getComponents();
		for (int i = 0;  i < centerPanel.getComponentCount();  i++) {		
			if (comps[i] instanceof CollapsiblePanel) {
				CollapsiblePanel c = (CollapsiblePanel)comps[i];
				if (node.getText().equals(c.getTitle())) {
					c.expand();
					c.scrollRectToVisible(new Rectangle(new Point(0,0), c.getMaximumSize()));
					break;
				}
			}
		}
	}

	private void zoomAll(boolean expand) {	
		Component[] comps = centerPanel.getComponents();
		for (int i = 0;  i < centerPanel.getComponentCount();  i++) {		
			if (comps[i] instanceof CollapsiblePanel) {
				CollapsiblePanel c = (CollapsiblePanel)comps[i];
				if (expand) c.expand();
				else c.collapse();
			}
		}
	}
	
	public void setView(MenuTreeNode node) {
		if (node.getText().equals(JPaveFrame.FilterContigsQuery)) {
			lblTitle.setText(node.getText());
			txtDesc.setText("Only the sequences that pass all filters will be shown.");
			if(getParentFrame().hasExpLevels())
				selLibraryPanel.setVisible(true);
			if (PValPanel != null)
				PValPanel.setVisible(true);
			uniprotPanel.setVisible(true);
			similarityPanel.setVisible(false);
			contigPanel.setVisible(true);
			if(SNPandORFPanel != null)
				SNPandORFPanel.setVisible(true);
			if(GOPanel != null)
				GOPanel.setVisible(true);
		}
		else if (node.getText().equals(JPaveFrame.FilterPairsQuery)) {
			lblTitle.setText(node.getText());
			txtDesc.setText("Only the similar pairs that pass all filters will be shown.");
	
			if(getParentFrame().hasExpLevels())
				selLibraryPanel.setVisible(false);
			if (PValPanel != null)
				PValPanel.setVisible(false);
			uniprotPanel.setVisible(false);
			similarityPanel.setVisible(true);
			contigPanel.setVisible(false);
			if(SNPandORFPanel != null)
				SNPandORFPanel.setVisible(false);
			if(GOPanel != null)
				GOPanel.setVisible(false);
		}
		txtDesc.setMaximumSize(txtDesc.getPreferredSize()); // needed to prevent vertical stretching
	}

	private ActionListener btnListener = new ActionListener() {
		public void actionPerformed(ActionEvent e)
		{
			if(e.getSource() == chkAbsoluteLibraryCounts || e.getSource() == chkNormalizedLibraryCounts) {
				updateLibraryString();
			}
		}
	};
	// 12/26/14 CAS added
	private ItemListener filterPvalListener = new ItemListener() {
		public void itemStateChanged(ItemEvent e) {
			setPvalEnabled(chkFilterPVal.isSelected());
		}
	};
	private ItemListener filterLibListener = new ItemListener() {
		public void itemStateChanged(ItemEvent e) {
			setLibEnabled(incLibraryCountPromptField.isSelected() || 
					exLibraryCountPromptField.isSelected() || 
					libraryComparePromptField.isSelected());
		}
	};
	private ItemListener filterItemListener = new ItemListener() {
		public void itemStateChanged(ItemEvent e) {
			Object o = e.getSource();

			// Contig General
			if (getParentFrame().hasNs() && o == cmbIncludeExcludeNs) {
				boolean show = (cmbIncludeExcludeNs.getValue() != FilterContigData.FILTER_NONE);
				MenuTreeNode n = contigNode.getChildWithName(GENERAL_HEADER).getChildAt(0);
				n.setText(cmbIncludeExcludeNs.toString());
				n.setVisible(show);		
			}
			else if (o == chkNumAligns) {
				boolean show = chkNumAligns.isSelected();
				MenuTreeNode n = contigNode.getChildWithName(GENERAL_HEADER).getChildAt(1);
				n.setText(chkNumAligns.toString());
				n.setVisible(show);
			}
			else if (o == chkCtgLength) {
				boolean show = chkCtgLength.isSelected();
				MenuTreeNode n = contigNode.getChildWithName(GENERAL_HEADER).getChildAt(2);
				n.setText(chkCtgLength.toString());
				n.setVisible(show);
			}
			else if (o == chkTotalExpLevel) {
				boolean show = chkTotalExpLevel.isSelected();
				MenuTreeNode n = contigNode.getChildWithName(GENERAL_HEADER).getChildAt(3);
				n.setText(chkTotalExpLevel.toString());
				n.setVisible(show);
			}
			else if (o == chkGreaterEqualSNPs) {
				boolean show = chkGreaterEqualSNPs.isSelected();
				MenuTreeNode n = contigNode.getChildWithName(GENERAL_HEADER).getChildAt(4);
				n.setText(chkGreaterEqualSNPs.toString());
				n.setVisible(show);
			}
			else if (o == chkLessEqualSNPs) {
				boolean show = chkLessEqualSNPs.isSelected();
				MenuTreeNode n = contigNode.getChildWithName(GENERAL_HEADER).getChildAt(5);
				n.setText(chkLessEqualSNPs.toString());
				n.setVisible(show);
			}
			else if (o == cmbIncludeExcludeNotes) {
				boolean show = (cmbIncludeExcludeNotes.getValue() != FilterContigData.FILTER_NONE);
				MenuTreeNode n = contigNode.getChildWithName(GENERAL_HEADER).getChildAt(6);
				n.setText(cmbIncludeExcludeNotes.toString());
				n.setVisible(show);		
			}
			else if (o == chkAllPVal)
			{
				for (JCheckBox chk : colSelectPVal )
				{
					chk.setSelected(chkAllPVal.isSelected());
				}
			}
			else if (o == chkUpOnlyAll)
			{
				for(int x=0; x<colSelectPVal.length; x++) 
				{
					colUpOnly[x].setSelected(true);
				}
			}
			else if (o == chkDownOnlyAll)
			{
				for(int x=0; x<colSelectPVal.length; x++) 
				{
					colDownOnly[x].setSelected(true);
				}
			}
			else if (o == chkUpDownAll)
			{
				for(int x=0; x<colSelectPVal.length; x++) 
				{
					colUpDown[x].setSelected(true);
				}
			}
			// Coding Region
			else if (o == chkHasORF) {
				boolean show = chkHasORF.isSelected();
				MenuTreeNode n = contigNode.getChildWithName(SNP_ORF_HEADER).getChildAt(0);
				n.setText(chkHasORF.toString());
				n.setVisible(show);
			}
			else if (o == chkHasProteinORF) {
				MenuTreeNode n = contigNode.getChildWithName(SNP_ORF_HEADER).getChildAt(3);
				n.setText("AND: Has a strong protein confirmation");
				n.setVisible(chkHasProteinORF.isSelected());	
			}
			else if (o == chkHasBothUTRs) {
				MenuTreeNode n = contigNode.getChildWithName(SNP_ORF_HEADER).getChildAt(3);
				n.setText("AND: Has a start and stop codon");
				n.setVisible(chkHasBothUTRs.isSelected());	
			}
			else if(o == chkFilterPVal || o == cmbBoolPVal) {
				MenuTreeNode n = contigNode.getChildWithName(PVAL_HEADER).getChildAt(0);
				n.setText( "< " + txtPVal.getText());
				n.setVisible(chkFilterPVal.isSelected());
				n = contigNode.getChildWithName(PVAL_HEADER).getChildAt(1);
				n.setText((String)cmbBoolPVal.getSelectedItem());
				n.setVisible(chkFilterPVal.isSelected());
				
				int selCount = 0;
				for(int x=0; x<colSelectPVal.length; x++) {
					if(colSelectPVal[x].isSelected())
						selCount++;
				}
				n = contigNode.getChildWithName(PVAL_HEADER).getChildAt(2);
				n.setText("PVals: " + selCount);
				n.setVisible(chkFilterPVal.isSelected());
			}
			// DB Hit
			else if ((o == chkHasBestDBHit) || (o == chkNoAnno) || (o == chkDBHitLen) || (o == chkDBHitBitScore) || (o == chkDBHitEVal) || (o == chkDBHitIdent)) {
				refreshBestDBHit();
			}
						
			// Filter Pairs Query - Similarity
			else if (o == chkPairsCutoffs) {
				MenuTreeNode n = pairNode.getChildWithName("Similarity").getChildAt(1);
				n.setVisible(chkPairsCutoffs.isSelected());	
			}
			else if (o == chkPairsCompareBestHit) {
				MenuTreeNode n = pairNode.getChildWithName("Similarity").getChildAt(2);
				n.setVisible(chkPairsCompareBestHit.isSelected());	
			}
			if(getParentFrame().hasExpLevels()) {
				updateLibraryString();
				updateLibSelectStatus();
			}
		}
	};
	
	private void refreshBestDBHit() {
		MenuTreeNode dbHitHeader = contigNode.getChildWithName(BEST_DB_HIT_HEADER);
		boolean isBestHitSelected = chkHasBestDBHit.isSelected();

		MenuTreeNode n = dbHitHeader.getChildAt(1);
		n.setText(chkHasBestDBHit.getText());
		n.setVisible(isBestHitSelected);

		if(chkNoAnno != null) {
			n = dbHitHeader.getChildAt(2);
			n.setText(chkNoAnno.getText());
			n.setVisible(isBestHitSelected);
		}

		n = dbHitHeader.getChildAt(3);
		n.setText(chkDBHitLen.toString());
		n.setVisible(isBestHitSelected && chkDBHitLen.isSelected());

		n = dbHitHeader.getChildAt(4);
		n.setText(chkDBHitBitScore.toString());
		n.setVisible(isBestHitSelected && chkDBHitBitScore.isSelected());

		n = dbHitHeader.getChildAt(5);
		n.setText(chkDBHitEVal.toString());
		n.setVisible(isBestHitSelected && chkDBHitEVal.isSelected());

		n = dbHitHeader.getChildAt(6);
		n.setText(chkDBHitIdent.toString());
		n.setVisible(isBestHitSelected && chkDBHitIdent.isSelected());
	}
	
	private void updateLibraryString()
	{
		String temp = "";
		Vector<String> message = new Vector<String> ();

		if(getNumSelectedIncludeLibs() == 0 && getNumSelectedExcludeLibs() == 0) {
			contigNode.getChildWithName(LIBRARY_HEADER).hideChildren();
			return;
		}
		
		contigNode.getChildWithName(LIBRARY_HEADER).showChildren();

		temp = "Filter by ";
		if(chkAbsoluteLibraryCounts.isSelected())
			temp += "absolute value";
		else
			temp += "normalized value";
		message.add(temp);
		temp = "";
		
		message.add("Libraries included: " + getNumSelectedIncludeLibs());
		message.add("Libraries excluded: " + getNumSelectedExcludeLibs());
				
		if(incLibraryCountPromptField.isSelected() && getNumSelectedIncludeLibs() > 0)
			message.add("Include: Read count at least " + incLibraryCountPromptField.getNum() + 
					" from " + incLibraryCountPromptField.getOption2Text() + " lib");
		if(exLibraryCountPromptField.isSelected() && getNumSelectedExcludeLibs() > 0)
			message.add("Exclude: Read count at most " + exLibraryCountPromptField.getNum() + 
					" from " + exLibraryCountPromptField.getOption2Text() + " lib");
		if(libraryComparePromptField.isSelected() && getNumSelectedIncludeLibs() > 0 && getNumSelectedExcludeLibs() > 0)
			message.add(libraryComparePromptField.getNum() + "-fold " + 
					libraryComparePromptField.getOption1Text() + " from " + 
					libraryComparePromptField.getOption2Text() + " included lib vs. " + 
					libraryComparePromptField.getOption3Text() + " excluded lib"); // CAS 11/28/12 was Option2
		
		int pos = 0;
		Iterator<String> strIter = message.iterator();
		while(strIter.hasNext()) {
			contigNode.getChildWithName(LIBRARY_HEADER).getChildAt(pos++).setText(strIter.next());
		}
		
		for(; pos < contigNode.getChildWithName(LIBRARY_HEADER).getChildCount(); pos++)
			contigNode.getChildWithName(LIBRARY_HEADER).getChildAt(pos).setVisible(false);		
	}
	
	public boolean isAbsoluteLibCountSelected() { return chkAbsoluteLibraryCounts.isSelected(); }
	
	public int getNumSelectedIncludeLibs() {
		int numResults = 0;
		for(int x=0; x<chkIncludeLibs.length; x++)
			if(chkIncludeLibs[x].isSelected())
				numResults++;
		return numResults;
	}
	
	public int getNumSelectedExcludeLibs() {
		int numResults = 0;
		for(int x=0; x<chkExcludeLibs.length; x++)
			if(chkExcludeLibs[x].isSelected())
				numResults++;
		return numResults;
	}
	
	public String [] getSelectedIncludeLibs() {
		int numResults = 0;
		for(int x=0; x<chkIncludeLibs.length; x++)
			if(chkIncludeLibs[x].isSelected())
				numResults++;
		
		if(numResults == 0) return null;
		
		String [] retVal = new String [numResults];
		int pos = 0;
		for(int x=0; x<chkIncludeLibs.length; x++)
			if(chkIncludeLibs[x].isSelected()) {
				retVal[pos++] = chkIncludeLibs[x].getText();
			}
		return retVal;
	}
	
	public String [] getSelectedExcludeLibs() {
		int numResults = 0;
		for(int x=0; x<chkExcludeLibs.length; x++)
			if(chkExcludeLibs[x].isSelected())
				numResults++;
		
		if(numResults == 0) return null;
		
		String [] retVal = new String [numResults];
		int pos = 0;
		for(int x=0; x<chkExcludeLibs.length; x++)
			if(chkExcludeLibs[x].isSelected())
				retVal[pos++] = chkExcludeLibs[x].getText();
		
		return retVal;
	}
	
	public String [] getSelectedPValColumns() {
		Vector<String> theColumns = new Vector<String> ();
		if(colSelectPVal != null) {
			for(int x=0; x<colSelectPVal.length; x++) {
				if(colSelectPVal[x].isSelected())
					theColumns.add(colSelectPVal[x].getText());
			}
		}
		return theColumns.toArray(new String[0]);
	}
	public boolean [] getSelectedUpColumns() {
		Vector<Boolean> theColumns = new Vector<Boolean> ();
		if(colSelectPVal != null) {
			for(int x=0; x<colSelectPVal.length; x++) {
				if(colSelectPVal[x].isSelected())
					theColumns.add(colUpOnly[x].isSelected());
			}
		}
		boolean[] ret = new boolean[theColumns.size()];
		for (int i = 0; i < ret.length; i++)
		{
			ret[i] = theColumns.get(i);
		}
		return ret;
	}	
	public boolean [] getSelectedDownColumns() {
		Vector<Boolean> theColumns = new Vector<Boolean> ();
		if(colSelectPVal != null) {
			for(int x=0; x<colSelectPVal.length; x++) {
				if(colSelectPVal[x].isSelected())
					theColumns.add(colDownOnly[x].isSelected());
			}
		}
		boolean[] ret = new boolean[theColumns.size()];
		for (int i = 0; i < ret.length; i++)
		{
			ret[i] = theColumns.get(i);
		}
		return ret;
	}	
	public String [] getAllLibraryNames(boolean notused) // was normalize but calling routines add prefix 
	{
		return libColumns;
		/* CAS 12/28/14 
		if(chkIncludeLibs == null)
			return new String[0];
		String [] retVal = new String[chkIncludeLibs.length];
		for(int x=0; x<chkIncludeLibs.length; x++)
			retVal[x] = chkIncludeLibs[x].getText().
				substring(0, chkIncludeLibs[x].getText().indexOf(':')).trim();
		
		return retVal;
		*/
	}
	public String [] getAllLibraryTitles() {
		return libTitles;
	}
	
	public String [] getAllContigSetNames(boolean normalized) {
		if(ctgSetNameList == null) return null;
		
		String [] retVal = new String[ctgSetNameList.length/2];
		
		String mode = normalized?"N":"";
		int index = 0;
		for(int x=0; x<ctgSetNameList.length; x+=2)
			retVal[index++] = mode + ctgSetNameList[x];
		
		return retVal;
	}
	 
	public String [] getAllPValNames() {
		return pValColumns;
	}
	// CAS 12/28/14 added
	public String [] getAllPValTitles() {
		return pValTitles;
	}
	
	public void restoreAnnoDefaults() {
		if (chkAnnoDB==null) return; 
		for(int x=0; x<chkAnnoDB.length; x++)
			chkAnnoDB[x].setSelected(true);
		chkAnnoDBSelAll.setSelected(true);
	}
	
	public void restoreLibraryDefaults()
	{
		chkNormalizedLibraryCounts.setSelected(true);
		incLibraryCountPromptField.setSelected(false);
		incLibraryCountPromptField.setOption2(0);
		incLibraryCountPromptField.setNum(1);
		exLibraryCountPromptField.setSelected(false);
		exLibraryCountPromptField.setOption2(0);
		exLibraryCountPromptField.setNum(0);
		libraryComparePromptField.setSelected(false);
		libraryComparePromptField.setNum(2);
		libraryComparePromptField.setOption1(1);
		libraryComparePromptField.setOption2(0);
		libraryComparePromptField.setOption3(0);
		
		libSelAll.setSelected(true);
		for(int x=0; x<chkIncludeLibs.length; x++)
			chkIncludeLibs[x].setSelected(true);
		
		libCheckUnChecked.setSelected(false);
		for(int x=0; x<chkExcludeLibs.length; x++)
			chkExcludeLibs[x].setSelected(false);
	}
	
	private void selectAllIncLibsClicked() {
		boolean selected = libSelAll.isSelected();
		for(int x=0; x<chkIncludeLibs.length; x++)
			chkIncludeLibs[x].setSelected(selected);
	}
	
	private boolean areAllIncLibsSelected() {
		boolean retVal = true;
		for(int x=0; x<chkIncludeLibs.length && retVal; x++) 
			retVal &= chkIncludeLibs[x].isSelected();
		return retVal;
	}
	
	private void selectUncheckedClicked() {
		for(int x=0; x<chkIncludeLibs.length; x++) {
			if(libCheckUnChecked.isSelected())
				chkExcludeLibs[x].setSelected(!chkIncludeLibs[x].isSelected());
			else
				chkExcludeLibs[x].setSelected(false);
		}
	}
	
	private boolean areExCheckedForIncUnChecked() {
		boolean retVal = true;
		
		for(int x=0; x<chkIncludeLibs.length && retVal; x++)
			retVal &= (chkIncludeLibs[x].isSelected() != chkExcludeLibs[x].isSelected());
		return retVal;
	}
	
	private void updateUnCheckList() {
		if(libCheckUnChecked.isSelected())
			for(int x=0; x<chkIncludeLibs.length; x++)
				chkExcludeLibs[x].setSelected(!chkIncludeLibs[x].isSelected());
	}
	
	//Loads the contig sets names. While contig sets are no longer queried, the will
	//still be loaded here in case that changes, and for consistency of design
	private void loadContigSetColumns() {
		try {
			ctgSetNameList = theAssemblies.getContigSets();
		} catch(Exception e) {
			ErrorReport.reportError(e);
		}
	}
    // XXX
	private void loadPValColumns() {
		try {
			pValColumns = theAssemblies.getPColumns();
			if (pValColumns!=null || pValColumns.length==0) 
				pValTitles = theAssemblies.getPTitle(pValColumns);
			
			String [] x = theAssemblies.getLibraries(); // lib1, title1, lib2, title2, etc
			libColumns = new String [x.length/2];
			libTitles = new String [x.length/2];
			for (int i=0, j=0; i<x.length; i++, j++) {
				libColumns[j] = x[i];
				i++;
				libTitles[j] = (x[i]!=null) ? x[i] : "";
			}
		}
		catch(Exception e) {
			ErrorReport.reportError(e);
		}
	}
	
	private JComponent createSelectPVal( FilterContigData theFilter ) {
		if (pValColumns==null || pValColumns.length==0) return null;
		
		int pLen=pValColumns.length;
		boolean hasUpDown = false;
		try {
			// databases built in 2013 did not distinguish between up and down DE (down is now neg)
			hasUpDown = theAssemblies.hasUpDownDE();
		} catch (Exception e) {
			ErrorReport.reportError(e, "Internal error: select DE p-values");
		}
		// XXX
		
		JComponent thePanel = new CollapsiblePanel(PVAL_HEADER, PVAL_DESCRIPTION);
		chkFilterPVal = new JCheckBox();
		chkFilterPVal.addItemListener(filterPvalListener);
		
		cmbBoolPVal = new JComboBox();
		cmbBoolPVal.setBackground(Color.WHITE);
		cmbBoolPVal.addItem("EVERY");
		cmbBoolPVal.addItem("ANY");
		cmbBoolPVal.setSelectedIndex(0);
		cmbBoolPVal.setMaximumSize(cmbBoolPVal.getPreferredSize());
		cmbBoolPVal.setMinimumSize(cmbBoolPVal.getPreferredSize());
		
		JLabel lblPVal = new JLabel("p-value less than");
		lblPVal.setBackground(Color.WHITE);
		txtPVal = new JTextField(10);
		txtPVal.setText("0.05");
		txtPVal.setMaximumSize(txtPVal.getPreferredSize());
		txtPVal.setMinimumSize(txtPVal.getPreferredSize());
		
		JPanel row = new JPanel();
		row.setLayout(new BoxLayout(row, BoxLayout.LINE_AXIS));
		row.setBackground(Color.WHITE);
		
		row.add(chkFilterPVal);
		row.add(Box.createHorizontalStrut(5));
		row.add(cmbBoolPVal);
		row.add(Box.createHorizontalStrut(5));
		row.add(lblPVal);
		row.add(Box.createHorizontalStrut(5));
		row.add(txtPVal);
		
		addRowToPanel(row, thePanel);
		thePanel.add(Box.createVerticalStrut(10));
		
		row = new JPanel();
		row.setBackground(Color.white);
		row.setLayout(new BoxLayout(row, BoxLayout.LINE_AXIS));
		row.add(Box.createHorizontalStrut(5));
		row.add(new JLabel("Select one or more DE columns"));
		addRowToPanel(row, thePanel);
		
		// CAS 12/28/14 add title
		colSelectPVal = new JCheckBox[pLen];
		colUpDown = new JRadioButton[pLen];
		colUpOnly = new JRadioButton[pLen];
		colDownOnly = new JRadioButton[pLen];
		colpValTitle = new JLabel[pLen];
		for(int x=0; x<pLen; x++) {
			row = new JPanel();
			row.setBackground(Color.white);
			row.setLayout(new BoxLayout(row, BoxLayout.LINE_AXIS));
			
			JPanel sr = new JPanel();
			sr.setBackground(Color.white);
			sr.setLayout(new BoxLayout(sr, BoxLayout.LINE_AXIS));
		
			colSelectPVal[x] = new JCheckBox(pValColumns[x]);
			colSelectPVal[x].addItemListener(filterItemListener);
			
			sr.add(colSelectPVal[x]);
			sr.add(Box.createHorizontalGlue());
			sr.setMinimumSize(new Dimension(160,sr.getPreferredSize().height));
			row.add(sr);
			
			colUpDown[x] = new JRadioButton("Either"); colUpDown[x].setBackground(Color.white);
			colUpOnly[x] = new JRadioButton("Up"); colUpOnly[x].setBackground(Color.white);
			colDownOnly[x] = new JRadioButton("Down"); colDownOnly[x].setBackground(Color.white);
			ButtonGroup bg2 = new ButtonGroup();
			bg2.add(colUpDown[x]);
			bg2.add(colDownOnly[x]);
			bg2.add(colUpOnly[x]);
			colUpDown[x].setSelected(true);
			
			if (hasUpDown)
			{
				row.add(colUpOnly[x]);
				row.add(Box.createHorizontalStrut(5));
				row.add(colDownOnly[x]);
				row.add(Box.createHorizontalStrut(5));
				row.add(colUpDown[x]);
			}
			row.add(Box.createHorizontalStrut(30));
			colpValTitle[x] = new JLabel(pValTitles[x]);
			row.add(colpValTitle[x]); 
			addRowToPanel(row, thePanel);
		}
		row = new JPanel();
		row.setBackground(Color.white);
		row.setLayout(new BoxLayout(row, BoxLayout.LINE_AXIS));
		JPanel sr = new JPanel();
		sr.setBackground(Color.white);
		sr.setLayout(new BoxLayout(sr, BoxLayout.LINE_AXIS));
		chkAllPVal = new JCheckBox("Check/uncheck all"); 
		chkAllPVal.addItemListener(filterItemListener);
		sr.add(chkAllPVal);
		sr.add(Box.createHorizontalGlue());
		sr.setMinimumSize(new Dimension(160,sr.getPreferredSize().height));
		if (pLen>1) row.add(sr);
		
		chkUpDownAll = new JRadioButton("Either"); chkUpDownAll.setBackground(Color.white);
		chkUpOnlyAll = new JRadioButton("Up"); chkUpOnlyAll.setBackground(Color.white);
		chkDownOnlyAll = new JRadioButton("Down"); chkDownOnlyAll.setBackground(Color.white);
		chkUpDownAll.addItemListener(filterItemListener);
		chkUpOnlyAll.addItemListener(filterItemListener);
		chkDownOnlyAll.addItemListener(filterItemListener);
		ButtonGroup allbg = new ButtonGroup();
		allbg.add(chkUpDownAll); 
		allbg.add(chkUpOnlyAll); 
		allbg.add(chkDownOnlyAll);
		chkUpDownAll.setSelected(true);
		
		if (hasUpDown && pLen>1) {
			row.add(chkUpOnlyAll);
			row.add(Box.createHorizontalStrut(5));
			row.add(chkDownOnlyAll);
			row.add(Box.createHorizontalStrut(5));
			row.add(chkUpDownAll);
			thePanel.add(Box.createVerticalStrut(5));
			addRowToPanel(row, thePanel);
		}
		setPvalEnabled(false);
		
		MenuTreeNode node = contigNode.getChildWithName(PVAL_HEADER);
		node.addChild(new MenuTreeNode());
		node.addChild(new MenuTreeNode());
		node.addChild(new MenuTreeNode());
		node.hideChildren();
		return thePanel;
	}
	// 12/26/14 CAS disable libraries unless a query was selected
	private JComponent createSelectLibrary( FilterContigData theFilter) {
		JComponent thePanel = new CollapsiblePanel(LIBRARY_HEADER, LIBRARY_DESCRIPTION);
		String [] libLabels = {"EVERY", "ANY"};
		String [] foldRange = {"UP", "DOWN", "UP/DOWN" };

		chkAbsoluteLibraryCounts = new JRadioButton("use counts");
		chkAbsoluteLibraryCounts.setBackground(Color.WHITE);
		
		String ppx = "use RPKM ";
		chkNormalizedLibraryCounts = new JRadioButton(ppx);
		chkNormalizedLibraryCounts.setBackground(Color.WHITE);
		chkAbsoluteLibraryCounts.addActionListener(btnListener);
		chkNormalizedLibraryCounts.addActionListener(btnListener);
		
		ButtonGroup libModeGroup = new ButtonGroup();
		libModeGroup.add(chkAbsoluteLibraryCounts);
		libModeGroup.add(chkNormalizedLibraryCounts);
		chkNormalizedLibraryCounts.setSelected(true);
		
		JPanel libModePanel = new JPanel();
		libModePanel.setBackground(Color.white);
		libModePanel.setLayout(new BoxLayout(libModePanel, BoxLayout.LINE_AXIS));
		libModePanel.add(chkAbsoluteLibraryCounts);
		libModePanel.add(Box.createHorizontalStrut(20));
		libModePanel.add(chkNormalizedLibraryCounts);
		libModePanel.setMaximumSize(libModePanel.getPreferredSize());
		addRowToPanel(libModePanel, thePanel);
		
		incLibraryCountPromptField = new LibraryPromptField(
				"At least ", 1, " from ", 
				null, null, 
				libLabels, " included library",  
				null, null, "   ", defaultLabelNumDims, 
				filterLibListener, 1, 0, 0, true);
		incLibraryCountPromptField.setSelected(false); 
		
		exLibraryCountPromptField = new LibraryPromptField(
				"At most ", 0, " from ", 
				null, null, 
				libLabels, " excluded library", 
				null, null, "   ", defaultLabelNumDims, 
				filterLibListener, 0, 0, 0, true);
		exLibraryCountPromptField.setSelected(false); 
		
		libraryComparePromptField = new LibraryPromptField(
				"Minimum ", 2, "-fold ", 
				foldRange,  "from every included library compared to every excluded library", 
				null, "  ", 
				null, null, "  ", defaultLabelNumDims, 
				filterLibListener, 1, 0, 0, true);
		
		thePanel.add(Box.createVerticalStrut(5));
		addRowToPanel(incLibraryCountPromptField, thePanel);
		thePanel.add(Box.createVerticalStrut(5));
		addRowToPanel(exLibraryCountPromptField, thePanel);
		thePanel.add(Box.createVerticalStrut(5));
		addRowToPanel(libraryComparePromptField, thePanel);		
		thePanel.add(Box.createVerticalStrut(10));
		
		addRowToPanel(new JLabel("Include Libraries"), thePanel);
		
		chkIncludeLibs = new JCheckBox[libColumns.length];
		txtIncBoolState = new JTextField[libColumns.length];
		labelIncLibs = new JLabel[libColumns.length];
		
		for(int x=0; x<chkIncludeLibs.length; x++) {
			chkIncludeLibs[x] = new JCheckBox(libColumns[x]);
			
			chkIncludeLibs[x].setSelected(false);
			chkIncludeLibs[x].setBackground(Color.WHITE);
			chkIncludeLibs[x].addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					libSelAll.setSelected(areAllIncLibsSelected());
					updateUnCheckList();
					getParentFrame().getFieldTab().filterListUpdated();
					updateLibraryString();
				}
			});
			txtIncBoolState[x] = new JTextField(10);
			txtIncBoolState[x].setEditable(false);
			txtIncBoolState[x].setBackground(Color.WHITE);
			txtIncBoolState[x].setBorder(BorderFactory.createEmptyBorder());
			txtIncBoolState[x].setMinimumSize(defaultLabelNumDims);
			
			JPanel temp = new JPanel();
			temp.setBackground(Color.white);
			temp.setLayout(new BoxLayout(temp, BoxLayout.LINE_AXIS));
			
			JPanel chk = new JPanel();
			chk.setBackground(Color.white);
			chk.setLayout(new BoxLayout(chk, BoxLayout.LINE_AXIS));
			chk.add(chkIncludeLibs[x]);
			chk.add(Box.createHorizontalGlue());
			chk.setMinimumSize(new Dimension(160,chk.getPreferredSize().height));
			temp.add(chk);
			
			temp.add(Box.createHorizontalStrut(2));
			temp.add(txtIncBoolState[x]);
			
			temp.add(Box.createHorizontalStrut(20));
			labelIncLibs[x] = new JLabel(libTitles[x]);
			temp.add(labelIncLibs[x]);
			
			addRowToPanel(temp, thePanel);
		}

		thePanel.add(new JSeparator());
		libSelAll = new JCheckBox("check/uncheck all");
		libSelAll.setSelected(true);
		libSelAll.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				selectAllIncLibsClicked();
				updateLibraryString();
			}
		});
		addRowToPanel(libSelAll, thePanel);
		thePanel.add(new JSeparator());
		
		thePanel.add(Box.createVerticalStrut(10));
		addRowToPanel(new JLabel("Exclude Libraries"), thePanel);

		chkExcludeLibs = new JCheckBox[libColumns.length];
		txtExBoolState = new JTextField[libColumns.length];
		labelExLibs = new JLabel[libColumns.length];
		for(int x=0; x<chkExcludeLibs.length; x++) { // XXX CAS 12/28/14
			chkExcludeLibs[x] = new JCheckBox(libColumns[x]);
			chkExcludeLibs[x].setBackground(Color.WHITE);
			chkExcludeLibs[x].addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					libCheckUnChecked.setSelected(areExCheckedForIncUnChecked());
					getParentFrame().getFieldTab().filterListUpdated();
					updateLibraryString();
				}
			});
			txtExBoolState[x] = new JTextField("    ");
			txtExBoolState[x].setEditable(false);
			txtExBoolState[x].setBackground(Color.WHITE);
			txtExBoolState[x].setBorder(BorderFactory.createEmptyBorder());
			txtExBoolState[x].setMinimumSize(defaultLabelNumDims);
			
			JPanel temp = new JPanel();
			temp.setBackground(Color.white);
			temp.setLayout(new BoxLayout(temp, BoxLayout.LINE_AXIS));
			
			JPanel chk = new JPanel();
			chk.setBackground(Color.white);
			chk.setLayout(new BoxLayout(chk, BoxLayout.LINE_AXIS));
			chk.add(chkExcludeLibs[x]);
			chk.add(Box.createHorizontalGlue());
			chk.setMinimumSize(new Dimension(160,chk.getPreferredSize().height));
			temp.add(chk);
			
			temp.add(Box.createHorizontalStrut(2));
			temp.add(txtExBoolState[x]);
			
			temp.add(Box.createHorizontalStrut(20));
			labelExLibs[x] = new JLabel(libTitles[x]);
			temp.add(labelExLibs[x]);
		
			addRowToPanel(temp, thePanel);
		}
		thePanel.add(new JSeparator());
		libCheckUnChecked = new JCheckBox("check all not included above");
		libCheckUnChecked.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				selectUncheckedClicked();
				updateLibraryString();
			}
		});
		addRowToPanel(libCheckUnChecked, thePanel);
		thePanel.add(new JSeparator());
		thePanel.add(Box.createVerticalStrut(10));
		
		thePanel.add(Box.createVerticalStrut(5));

		MenuTreeNode node = contigNode.getChildWithName(LIBRARY_HEADER);
		node.addChild(new MenuTreeNode());
		node.addChild(new MenuTreeNode());
		node.addChild(new MenuTreeNode());
		node.addChild(new MenuTreeNode());
		node.addChild(new MenuTreeNode());
		node.addChild(new MenuTreeNode());
		node.addChild(new MenuTreeNode());
		node.addChild(new MenuTreeNode());
		node.addChild(new MenuTreeNode());
		node.addChild(new MenuTreeNode());
		node.addChild(new MenuTreeNode());

		updateUnCheckList();
		updateLibraryString();
		setLibEnabled(false);
		return thePanel;
	}

	private JComponent createContigFilter ( FilterContigData theFilter )
	{	
		// Create the General  panel
		JComponent thePanel = new CollapsiblePanel(GENERAL_HEADER, GENERAL_DESCRIPTION);
		
		if(getParentFrame().hasNs()) {
			cmbIncludeExcludeNs = new IncludeExcludeWidget( "Has N's:", "Yes", "No", "Ignore", 
														theFilter.getFilterHasNs() );
			cmbIncludeExcludeNs.addItemListener(filterItemListener);
			addRowToPanel( cmbIncludeExcludeNs, thePanel );
		}
		
		if (tcwFrame.hasAssembly()) {
		   chkNumAligns = new ToggleTextComboField(
				"",
				String.valueOf( theFilter.getCtgNumAligns() ),
				" # Alignments", BOOLEAN_LABELS, 1, defaultLabelDims, filterItemListener);
		   addRowToPanel ( chkNumAligns, thePanel );
		   thePanel.add(Box.createVerticalStrut(5));
		}
		chkCtgLength = new ToggleTextComboField(
				"",
				String.valueOf( theFilter.getCtgLength() ),
				" Length", BOOLEAN_LABELS, 1, defaultLabelDims, filterItemListener);
		addRowToPanel ( chkCtgLength, thePanel );
		thePanel.add(Box.createVerticalStrut(5));

		if(getParentFrame().hasExpLevels()) {
			chkTotalExpLevel = new ToggleTextComboField(
					"",
					String.valueOf( theFilter.getCtgTotalExpLevel() ),
					" Total Read Count", BOOLEAN_LABELS, 1, defaultLabelDims, filterItemListener);
			addRowToPanel ( chkTotalExpLevel, thePanel );
		}
		
		cmbIncludeExcludeNotes = new IncludeExcludeWidget( "Has a Remark: ", "Yes", "No", "Ignore", 
				theFilter.getFilterHasNotes());
		cmbIncludeExcludeNotes.addItemListener(filterItemListener);
		addRowToPanel( cmbIncludeExcludeNotes, thePanel );
			
		// Add place-holder menu tree nodes to be configured by filterItemListener
		MenuTreeNode node = contigNode.getChildWithName("General");
		node.addChild(new MenuTreeNode());
		node.addChild(new MenuTreeNode());
		node.addChild(new MenuTreeNode());
		node.addChild(new MenuTreeNode());
		node.addChild(new MenuTreeNode());
		node.addChild(new MenuTreeNode());
		node.addChild(new MenuTreeNode());
		node.hideChildren();
		
		theFilter.setCtgNumAligns(true);
		return thePanel;
	}
	
	private JComponent createGOFilters ( FilterContigData theFilter ) {
		if(!tcwFrame.hasGOs())
			return null;
		
		JComponent thePanel = new CollapsiblePanel(GO_HEADER, GO_DESCRIPTION); 
		
		chkGOID = new ToggleTextField(
				"GO ID ",
				String.valueOf( theFilter.getGOID() ),
				"", defaultLabelDims, filterItemListener);
		
		addRowToPanel(chkGOID, thePanel);
		
		return thePanel;
	}

	private JComponent createCodingRegionFilters ( FilterContigData theFilter )
	{	
		boolean addedComps = false;
		JComponent thePanel = new CollapsiblePanel(SNP_ORF_HEADER, SNP_ORF_DESCRIPTION); 
		
		if(tcwFrame.hasAssembly()) {
			addedComps = true;
			// Has >= SNPs
			chkGreaterEqualSNPs = new ToggleTextField(
					"Has >= ",
					String.valueOf( theFilter.getGtrEquSNPs() ),
					" SNPs", defaultLabelDims, filterItemListener);
			addRowToPanel ( chkGreaterEqualSNPs, thePanel );
			
			// Has <= SNPs
			chkLessEqualSNPs = new ToggleTextField(
					"Has <= ",
					String.valueOf( theFilter.getLessEquSNPs() ),
					" SNPs", defaultLabelDims, filterItemListener);	
			addRowToPanel ( chkLessEqualSNPs, thePanel );
		}
		
		if(!tcwFrame.isProteinDB()) {
			addedComps = true;
			
			// Has ORF
			chkHasORF = new ToggleTextField(
					"Has ORF of >= ", String.valueOf( theFilter.getORFMinNT() ),
					" NT", defaultLabelDims, filterItemListener);
			addRowToPanel ( chkHasORF, thePanel );
	
			// Both UTRs
			chkHasProteinORF = new JCheckBox ( "Protein confirmation" );
			chkHasProteinORF.setSelected( theFilter.isProteinORF() );
			chkHasProteinORF.setBackground(Color.WHITE);
			chkHasProteinORF.addItemListener(filterItemListener); 
			addRowToPanel ( chkHasProteinORF, thePanel );	
			
			// Both UTRs
			chkHasBothUTRs = new JCheckBox ( "Has a start and stop codon" );
			chkHasBothUTRs.setSelected( theFilter.isBothUTRs() );
			chkHasBothUTRs.setBackground(Color.WHITE);
			chkHasBothUTRs.addItemListener(filterItemListener); 
			addRowToPanel ( chkHasBothUTRs, thePanel );		
		
			// Add place-holder menu tree nodes to be configured by filterItemListener
			MenuTreeNode node = contigNode.getChildWithName("SNPs and ORFs");
			node.addChild(new MenuTreeNode());
			node.addChild(new MenuTreeNode());
			node.addChild(new MenuTreeNode());
			node.addChild(new MenuTreeNode());
			node.hideChildren();
		}
		if(!addedComps)
			return null;
		return thePanel;
	}
	// CAS 12/16/14 added Lib and Pval enabled
	private void setLibEnabled(boolean enabled) {
		for(int x=0; x<chkIncludeLibs.length; x++) {
			chkIncludeLibs[x].setEnabled(enabled);
			labelIncLibs[x].setEnabled(enabled);
		}
		for(int x=0; x<chkExcludeLibs.length; x++) {
			chkExcludeLibs[x].setEnabled(enabled);
			labelExLibs[x].setEnabled(enabled);
		}
		libSelAll.setEnabled(enabled);
		libCheckUnChecked.setEnabled(enabled);
	}
	private void setPvalEnabled(boolean enabled) {
		for (int x=0; x<colSelectPVal.length; x++) {
			colSelectPVal[x].setEnabled(enabled);
			colUpDown[x].setEnabled(enabled);
			colDownOnly[x].setEnabled(enabled);
			colUpOnly[x].setEnabled(enabled);
			colpValTitle[x].setEnabled(enabled);
		}
		chkAllPVal.setEnabled(enabled);
		chkUpDownAll.setEnabled(enabled);
		chkDownOnlyAll.setEnabled(enabled);
		chkUpOnlyAll.setEnabled(enabled);
		txtPVal.setEnabled(enabled);
	}
	private void setBestHitEnabled(boolean enabled) {
		cmbFirstBest.setEnabled(enabled);
		cmbDBHitAndOr.setEnabled(enabled);
		chkDBHitLen.setEnabled(enabled);
		chkDBHitBitScore.setEnabled(enabled);
		chkDBHitEVal.setEnabled(enabled);
		chkDBHitIdent.setEnabled(enabled);
		if(chkAnnoDB != null)
			for(int x=0; x<chkAnnoDB.length; x++)
				chkAnnoDB[x].setEnabled(enabled);
		if(lblTaxoDB != null)
			for(int x=0; x<lblTaxoDB.length; x++)
				lblTaxoDB[x].setEnabled(enabled);
		if(chkAnnoDBSelAll != null)
			chkAnnoDBSelAll.setEnabled(enabled);
	}
		
	private boolean isAllAnnoSelected() {
		boolean retVal = true;
		for(int x=0; retVal && x<chkAnnoDB.length; x++)
			retVal = chkAnnoDB[x].isSelected();
		return retVal;
	}
	
	private JComponent createDBidFilters ( FilterContigData theFilter )
	{
		// High confidence UniProt hit rows
		JComponent thePanel = new CollapsiblePanel(BEST_DB_HIT_HEADER, BEST_DB_HIT_DESCRIPTION); 

		if(!(theFilter.hasAnnotation() || theFilter.hasNoAnnotation() || theFilter.hasEitherAnnotation()))
			theFilter.setEitherAnnotation(true);
		
		ButtonGroup annoGroup = new ButtonGroup();
		
		JPanel annoModes = new JPanel();
		annoModes.setBackground(Color.white);
		annoModes.setLayout(new BoxLayout(annoModes, BoxLayout.LINE_AXIS));
		annoModes.setAlignmentX(Component.LEFT_ALIGNMENT);
		
		// Contig has best hit
		chkHasBestDBHit = new JRadioButton("Annotated");
		chkHasBestDBHit.setBackground(Color.WHITE);
		chkHasBestDBHit.setSelected(theFilter.hasAnnotation());
		chkHasBestDBHit.addItemListener(new ItemListener() {
			public void itemStateChanged(ItemEvent arg0) {
				setBestHitEnabled(true);
			}
		});
		annoGroup.add(chkHasBestDBHit);
		chkHasBestDBHit.addItemListener(filterItemListener);
		annoModes.add(chkHasBestDBHit);
		annoModes.add(Box.createHorizontalStrut(5));
		
		chkNoAnno = new JRadioButton("No annotation");
		chkNoAnno.setBackground(Color.WHITE);
		chkNoAnno.setSelected(theFilter.hasNoAnnotation());
		chkNoAnno.addItemListener(new ItemListener() {
			public void itemStateChanged(ItemEvent arg0) {
				setBestHitEnabled(false);
			}
		});
		annoGroup.add(chkNoAnno);
		chkNoAnno.addItemListener(filterItemListener);
		annoModes.add(chkNoAnno);
		annoModes.add(Box.createHorizontalStrut(5));
		
		chkEitherAnno = new JRadioButton("Don't care");
		chkEitherAnno.setBackground(Color.WHITE);
		chkEitherAnno.setSelected(theFilter.hasEitherAnnotation());
		chkEitherAnno.addItemListener(new ItemListener() {
			public void itemStateChanged(ItemEvent arg0) {
				setBestHitEnabled(false);
			}
		});
		annoGroup.add(chkEitherAnno);
		annoModes.add(chkEitherAnno);
		addRowToPanel(annoModes, thePanel);

		cmbFirstBest = new IncludeExcludeWidget("Search", "Best Eval", "Best Anno", null, 0);
		cmbFirstBest.addItemListener(filterItemListener);
		addRowToPanel(cmbFirstBest, thePanel);
		
		cmbDBHitAndOr = new IncludeExcludeWidget( "", "AND", 
				"OR", null, FilterContigData.FILTER_AND );
		cmbDBHitAndOr.addItemListener(filterItemListener);
		JPanel bar5 = createHorzBar ( Box.createHorizontalStrut(SUBGROUP_INSET_WIDTH), 
				cmbDBHitAndOr );

		addRowToPanel( bar5, thePanel );
		
		// Hit Length
		thePanel.add(Box.createVerticalStrut(5));
		chkDBHitLen = new ToggleTextComboField(
				"Has ",
				String.valueOf( theFilter.getDBHitLen() ),
				" Alignment length", BOOLEAN_LABELS, 1, defaultLabelDims, filterItemListener);
		JPanel bar = createHorzBar ( Box.createHorizontalStrut(SUBGROUP_INSET_WIDTH), 
				chkDBHitLen );
		addRowToPanel ( bar, thePanel );
		thePanel.add(Box.createVerticalStrut(5));
		
		// Bit Score
		chkDBHitBitScore = new ToggleTextComboField(
				"Has ",
				String.valueOf( theFilter.getDBHitBitScore() ),
				" Bit Score", BOOLEAN_LABELS, 1, defaultLabelDims, filterItemListener);
		bar = createHorzBar ( Box.createHorizontalStrut(SUBGROUP_INSET_WIDTH), 
				chkDBHitBitScore );
		addRowToPanel ( bar, thePanel );
		thePanel.add(Box.createVerticalStrut(5));

		// EVal
		chkDBHitEVal = new ToggleTextComboField(
				"Has ",
				String.valueOf( theFilter.getDBHitEval() ),
				" E Value", BOOLEAN_LABELS, 0, defaultLabelDims, filterItemListener);
		bar = createHorzBar ( Box.createHorizontalStrut(SUBGROUP_INSET_WIDTH), 
				chkDBHitEVal );
		addRowToPanel ( bar, thePanel );
		thePanel.add(Box.createVerticalStrut(5));
		
		chkDBHitIdent = new ToggleTextComboField(
				"Has ",
				String.valueOf( theFilter.getDBHitIdentity() ),
				" % Identity", BOOLEAN_LABELS, 1, defaultLabelDims, filterItemListener);
		bar = createHorzBar ( Box.createHorizontalStrut(SUBGROUP_INSET_WIDTH), 
				chkDBHitIdent );
		addRowToPanel ( bar, thePanel );
		thePanel.add(Box.createVerticalStrut(5));
		
		String [] annoLabels = null;
		try {
			annoLabels = theAssemblies.getAnnoDBs();
		} catch(Exception e) {
			ErrorReport.reportError(e);
		}
	
		if(annoLabels.length > 0) {

			thePanel.add(Box.createVerticalStrut(10));
			
			//List of anno dbs			
			chkAnnoDB = new JCheckBox[annoLabels.length/2];
			lblTaxoDB = new JLabel[annoLabels.length/2];
			
			thePanel.add(new JSeparator());
			int labelIndex = 0;
			JPanel annoRow = new JPanel();
			annoRow.setAlignmentX(Component.LEFT_ALIGNMENT);
			annoRow.setLayout(new BoxLayout(annoRow, BoxLayout.LINE_AXIS));
			
			for(int x=0; x<lblTaxoDB.length; x++) {
				if(x>0 && x % NUM_COLUMNS_ANNO == 0) {
					addRowToPanel(annoRow, thePanel);
					annoRow = new JPanel();
					annoRow.setBackground(Color.white);
					annoRow.setAlignmentX(Component.LEFT_ALIGNMENT);
					annoRow.setLayout(new BoxLayout(annoRow, BoxLayout.LINE_AXIS));			
				}
				JPanel temp = new JPanel();
				temp.setBackground(Color.white);
				temp.setAlignmentX(Component.LEFT_ALIGNMENT);
				temp.setLayout(new BoxLayout(temp, BoxLayout.LINE_AXIS));
				
				chkAnnoDB[x] = new JCheckBox(annoLabels[labelIndex++] + "--");
				chkAnnoDB[x].addActionListener(new ActionListener() {
					public void actionPerformed(ActionEvent e) {
						if(!isAllAnnoSelected())
							chkAnnoDBSelAll.setSelected(false);
						else
							chkAnnoDBSelAll.setSelected(true);
					}
				});
				lblTaxoDB[x] = new JLabel(annoLabels[labelIndex++]);
				chkAnnoDB[x].setSelected(true);
				lblTaxoDB[x].setBackground(Color.white);
				temp.add(chkAnnoDB[x]);
				temp.add(lblTaxoDB[x]);
				
				int width = COLUMN_WIDTH_ANNO - (chkAnnoDB[x].getPreferredSize().width + lblTaxoDB[x].getPreferredSize().width);
				if(width > 0)
					temp.add(Box.createHorizontalStrut(width));
				annoRow.add(temp);
			}
			if(annoRow.getComponentCount() > 0)
				addRowToPanel(annoRow, thePanel);
			thePanel.add(new JSeparator());
			chkAnnoDBSelAll = new JCheckBox("check/uncheck All");
			chkAnnoDBSelAll.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent arg0) {
					boolean selected = chkAnnoDBSelAll.isSelected();
					
					for(int x=0; x<chkAnnoDB.length; x++)
						chkAnnoDB[x].setSelected(selected);
				}
			});
			chkAnnoDBSelAll.setSelected(true);
			addRowToPanel(chkAnnoDBSelAll, thePanel);
		}
		else {
			chkHasBestDBHit.setEnabled(false);
			chkNoAnno.setEnabled(false);
			chkEitherAnno.setEnabled(false);
		}

		setBestHitEnabled(chkHasBestDBHit.isSelected());

		// Add place-holder menu tree nodes to be configured by filterItemListener
		MenuTreeNode node = contigNode.getChildWithName(BEST_DB_HIT_HEADER);
		node.addChild(new MenuTreeNode());
		node.addChild(new MenuTreeNode());
		node.addChild(new MenuTreeNode());
		node.addChild(new MenuTreeNode());
		node.addChild(new MenuTreeNode());
		node.addChild(new MenuTreeNode());
		node.addChild(new MenuTreeNode());
		node.addChild(new MenuTreeNode());
		node.addChild(new MenuTreeNode());
		node.addChild(new MenuTreeNode());
		node.addChild(new MenuTreeNode());
		node.addChild(new MenuTreeNode());
		node.addChild(new MenuTreeNode());
		node.hideChildren();
		
		return thePanel;
	}

	private JComponent createPairsFilters ( FilterContigData theFilter )
	{	
		JComponent thePanel = new CollapsiblePanel("Similarity", "Based on dynamic programming");
		
		JPanel bar = null;

		// Across contigs		CAS 12/26/14 add (text) to make more obvious
		chkPairsCutoffs = new JCheckBox ( "Sequence Pairs (check this box when setting filters)" );
		chkPairsCutoffs.setBackground(Color.WHITE);
		chkPairsCutoffs.addItemListener(filterItemListener);
		addRowToPanel ( chkPairsCutoffs, thePanel );
			
		// Min NT HSR Len
		
		fldPairsHSRMinNTPercentID = createPercentTextField ( theQuery.getPairsHSRMinNTPercentID() ); 
		bar = createHorzBar ( Box.createHorizontalStrut(SUBGROUP_INSET_WIDTH), 
				new JLabel ( "Has >= " ), fldPairsHSRMinNTPercentID, 
				new JLabel ( "NT HSR %ID AND" ) );
		addRowToPanel ( bar, thePanel );	

		fldPairsHSRMinNTLen = createIntegerTextField ( theQuery.getPairsHSRMinNTLen() );
		bar = createHorzBar ( Box.createHorizontalStrut(SUBGROUP_INSET_WIDTH), 
				new JLabel ( "Has >= " ), fldPairsHSRMinNTLen, 
				new JLabel ( "NT HSR Len AND" ) );
		addRowToPanel ( bar, thePanel );

		fldPairsHSRMinNTPercentLen = createPercentTextField ( theQuery.getPairsHSRMinNTPercentLen() ); 
		bar = createHorzBar ( Box.createHorizontalStrut(SUBGROUP_INSET_WIDTH), 
				new JLabel ( "Has >= " ), fldPairsHSRMinNTPercentLen, 
				new JLabel ( "NT HSR %Len AND" ) );
		addRowToPanel ( bar, thePanel );	
		thePanel.add(Box.createVerticalStrut(15));
		
		fldPairsOLPMinNTPercentID = createPercentTextField ( theQuery.getPairsOLPMinNTPercentID() ); 
		bar = createHorzBar ( Box.createHorizontalStrut(SUBGROUP_INSET_WIDTH), 
				new JLabel ( "Has >= " ), fldPairsOLPMinNTPercentID, 
				new JLabel ( "NT OLP %ID AND" ) );
		addRowToPanel ( bar, thePanel );	

		fldPairsOLPMinNTLen = createIntegerTextField ( theQuery.getPairsOLPMinNTLen() );
		bar = createHorzBar ( Box.createHorizontalStrut(SUBGROUP_INSET_WIDTH), 
				new JLabel ( "Has >= " ), fldPairsOLPMinNTLen, 
				new JLabel ( "NT OLP Len AND" ) );
		addRowToPanel ( bar, thePanel );

		fldPairsOLPMinNTPercentLen = createPercentTextField ( theQuery.getPairsOLPMinNTPercentLen() ); 
		bar = createHorzBar ( Box.createHorizontalStrut(SUBGROUP_INSET_WIDTH), 
				new JLabel ( "Has >= " ), fldPairsOLPMinNTPercentLen, 
				new JLabel ( "NT OLP %Len AND" ) );
		addRowToPanel ( bar, thePanel );	
		thePanel.add(Box.createVerticalStrut(15));
		
		fldPairsHSRMinAAPercentID = createPercentTextField ( theQuery.getPairsHSRMinAAPercentID() ); 
		bar = createHorzBar ( Box.createHorizontalStrut(SUBGROUP_INSET_WIDTH), 
				new JLabel ( "Has >= " ), fldPairsHSRMinAAPercentID, 
				new JLabel ( "AA HSR %ID AND" ) );
		addRowToPanel ( bar, thePanel );	

		// Min AA HSR Len
		fldPairsHSRMinAALen = createIntegerTextField ( theQuery.getPairsHSRMinAALen() );
		bar = createHorzBar ( Box.createHorizontalStrut(SUBGROUP_INSET_WIDTH), 
				new JLabel ( "Has >= " ), fldPairsHSRMinAALen, 
				new JLabel ( "AA HSR Len AND" ) );
		addRowToPanel ( bar, thePanel );

		fldPairsHSRMinAAPercentLen = createPercentTextField ( theQuery.getPairsHSRMinAAPercentLen() ); 
		bar = createHorzBar ( Box.createHorizontalStrut(SUBGROUP_INSET_WIDTH), 
				new JLabel ( "Has >= " ), fldPairsHSRMinAAPercentLen, 
				new JLabel ( "AA HSR %Len AND" ) );
		addRowToPanel ( bar, thePanel );	
		thePanel.add(Box.createVerticalStrut(15));

		fldPairsOLPMinAAPercentID = createPercentTextField ( theQuery.getPairsOLPMinAAPercentID() ); 
		bar = createHorzBar ( Box.createHorizontalStrut(SUBGROUP_INSET_WIDTH), 
				new JLabel ( "Has >= " ), fldPairsOLPMinAAPercentID, 
				new JLabel ( "AA OLP %ID AND" ) );
		addRowToPanel ( bar, thePanel );	

		// Min AA HSR Len
		fldPairsOLPMinAALen = createIntegerTextField ( theQuery.getPairsOLPMinAALen() );
		bar = createHorzBar ( Box.createHorizontalStrut(SUBGROUP_INSET_WIDTH), 
				new JLabel ( "Has >= " ), fldPairsOLPMinAALen, 
				new JLabel ( "AA OLP Len AND" ) );
		addRowToPanel ( bar, thePanel );

		fldPairsOLPMinAAPercentLen = createPercentTextField ( theQuery.getPairsOLPMinAAPercentLen() ); 
		bar = createHorzBar ( Box.createHorizontalStrut(SUBGROUP_INSET_WIDTH), 
				new JLabel ( "Has >= " ), fldPairsOLPMinAAPercentLen, 
				new JLabel ( "AA OLP %Len AND" ) );
		addRowToPanel ( bar, thePanel );	

		// Similarity Compare Best Hit
		chkPairsCompareBestHit = new JCheckBox ( "Test For Contigs w/Same 1stBestHit" );
		chkPairsCompareBestHit.setBackground(Color.WHITE);
		
		// Add place-holder menu tree nodes to be configured by filterItemListener
		MenuTreeNode node = pairNode.getChildWithName("Similarity");
		node.addChild(new MenuTreeNode());
		node.addChild(new MenuTreeNode("Sequence Pairs"));
		node.hideChildren();
		
		return thePanel;
	}
	
	private boolean doDataValidation ( )
	{
		lblError.setVisible(false); 
		lblError.setText( " " ); // Clear out the existing error if any
		if ( failure != null ) {
			if ( failure.getBorder() instanceof CompoundBorder ) {
				CompoundBorder errBorder = (CompoundBorder)failure.getBorder();
				failure.setBorder( errBorder.getInsideBorder() );
			}
			failure.setForeground( Color.BLACK );
			failure = null;
		}
		
		try {
			// Get the UI settings in a temp object to see if everything passes validation
			getUISettings ( new QueryData ( theQuery.getType(), null, getParentFrame().getFrameID() ) );
		}
		catch ( DataValidationError err ) {
			handleDataValidationError ( err );
			if (debug) System.err.println( err );
			return false;
		}
		return true;	
	}
	
	private void handleDataValidationError ( DataValidationError err )
	{
		failure = err.getComponent();
		if (failure == null) return; 
		if ( failure instanceof JTextField )
		{
			Border in = failure.getBorder();
			Border out = BorderFactory.createLineBorder( Color.RED );
			failure.setBorder( BorderFactory.createCompoundBorder( out, in ) );
		}
		else
			failure.setForeground( Color.RED );
		failure.requestFocus();
		lblError.setText( err.getMessage() );
		lblError.setForeground( Color.RED );
		lblError.setVisible(true); 
	}
	
	private class DataValidationError extends Exception
	{
		DataValidationError ( JComponent inComponent, String inDescription )
		{
			super ( inDescription );
			theComponent = inComponent;
		}
		
		public JComponent getComponent () { return theComponent; }
		
		private JComponent theComponent = null; // The component that failed validation
	    private static final long serialVersionUID = 1;
	};
	
	private double getAndValidatePercent ( JTextField theField ) throws DataValidationError
	{
		try
		{
			double percent = Double.parseDouble( theField.getText() );
			if ( percent >= 0.0d && percent <= 100.0d )
				return percent /= 100.0d;
		}
		catch ( Exception err ) { 
			//ErrorReport.reportError(err); 
		}
		throw new DataValidationError ( theField, "The value entered is not a valid percent." );
	}
	
	private int getAndValidateInteger ( JTextField theField ) throws DataValidationError
	{
		try
		{
			int n = Integer.parseInt( theField.getText() );
			if ( n >= 0 )
				return n;
		}
		catch ( Exception err ) { 
			//ErrorReport.reportError(err); 
		}
		throw new DataValidationError ( theField, "The value entered is not a valid positive integer." );
	}
	
	private double getAndValidateDouble ( ToggleTextComboField theField ) throws DataValidationError
	{
		try
		{
			double n = Double.parseDouble( theField.getText() );
			if ( n >= 0.0d )
				return n;
		}
		catch ( Exception err ) { 
			//ErrorReport.reportError(err); 
		}
		throw new DataValidationError ( theField, "The value entered is not a valid double." );
	}
	
	private int getAndValidateInteger ( ToggleTextField theField ) throws DataValidationError
	{
		try
		{
			int n = Integer.parseInt( theField.getText() );
			if ( n >= 0 )
				return n;
		}
		catch ( Exception err ) { 
			// prints error on graphical dispplay
		}
		throw new DataValidationError ( theField, "The value entered is not a valid positive integer." );
	}
	
	private int getAndValidateInteger ( ToggleTextComboField theField ) throws DataValidationError
	{
		try
		{
			int n = Integer.parseInt( theField.getText() );
			if ( n >= 0 )
				return n;
		}
		catch ( Exception err ) { 
			// prints error on graphical dispplay
		}
		throw new DataValidationError ( theField, "The value entered is not a valid positive integer." );
	}
	
	// integer or percent value if "%" at end
	private JTextField createPercentTextField ( double dRatio )
	{
		return createTextField ( String.valueOf ( (int)( dRatio * 100.0 ) ) );
	}
	private JTextField createIntegerTextField ( int i )
	{
		return createTextField ( String.valueOf ( i ));
	}
	
	private JTextField createTextField ( String str )
	{
		JTextField edit = new JTextField ( str );
		edit.setPreferredSize ( defaultLabelDims );
		edit.setMaximumSize( defaultLabelDims );
		edit.setMinimumSize( defaultLabelDims );
		edit.addFocusListener(new FocusAdapter() {
			public void focusLost(FocusEvent e) {
				doDataValidation();
			}
		});
		return edit;
	}
	
	private JPanel createHorzBar ( Component comp1, Component comp2 )
	{
		return createHorzBar ( comp1, comp2, null, null, null );
	}

	private JPanel createHorzBar ( Component comp1, Component comp2, Component comp3, Component comp4 )
	{
		return createHorzBar ( comp1, comp2, comp3, comp4, null );
	}
	
	private JPanel createHorzBar ( Component comp1, Component comp2, Component comp3, Component comp4, Component comp5 )
	{
		JPanel panel = new JPanel ();
		panel.setLayout( new BoxLayout ( panel, BoxLayout.X_AXIS ) );
		panel.setBackground(Color.WHITE);

		addToHorzBar ( panel, comp1 );
		addToHorzBar ( panel, comp2 );
		addToHorzBar ( panel, comp3 );
		addToHorzBar ( panel, comp4 );	
		addToHorzBar ( panel, comp5 );	
		return panel;
	}
	
	private void addToHorzBar ( JPanel bar, Component comp )
	{
		if ( comp != null )
		{
			bar.add( comp );
			bar.add( Box.createHorizontalStrut(5) );
		}
	}
	
	private void addRowToPanel ( JComponent row, JComponent toPanel )
	{
		int nWidth = (int)row.getMinimumSize().getWidth();
		int nHeight = Math.max( (int)row.getPreferredSize().getHeight(), MIN_ROW_HEIGHT );
		row.setAlignmentX ( Component.LEFT_ALIGNMENT );
		row.setMinimumSize(   new Dimension ( nWidth, nHeight ) );
		row.setPreferredSize( new Dimension ( nWidth, nHeight ) );
		row.setMaximumSize(   new Dimension ( nWidth, nHeight ) );
		toPanel.add( row );
	}
	
	private void updateLibSelectStatus() {
		String incBool = "", exBool = "", foldIncBool = "", foldExBool = "";
		if(incLibraryCountPromptField.isSelected())
			incBool = incLibraryCountPromptField.getOption2()==0?"AND":"OR";
		if(exLibraryCountPromptField.isSelected())
			exBool = exLibraryCountPromptField.getOption2()==0?"AND":"OR";
		if(libraryComparePromptField.isSelected()) {
			foldIncBool = libraryComparePromptField.getOption2()==0?"AND":"OR";
			foldExBool = libraryComparePromptField.getOption3()==0?"AND":"OR";

			if(!incLibraryCountPromptField.isSelected())
				incBool = foldIncBool;
			if(!exLibraryCountPromptField.isSelected())
				exBool = foldExBool;
		} else {
			foldIncBool = incBool;
			foldExBool = exBool;
		}
				
		for(int x=0; x<txtIncBoolState.length; x++) {
			if(incBool.equals(foldIncBool))
				txtIncBoolState[x].setText(incBool);
			else
				txtIncBoolState[x].setText("");
		}
		
		for(int x=0; x<txtExBoolState.length; x++) {
			if(exBool.equals(foldExBool))
				txtExBoolState[x].setText(exBool);
			else
				txtExBoolState[x].setText("");
		}
	}
	
	private int getNumAnnoSelected() {
		int retVal = 0;
		for(int x=0; x<chkAnnoDB.length; x++)
			if(chkAnnoDB[x].isSelected())
				retVal++;
		return retVal;
	}
	
	private String [] getSelectedAnnoDBTypes() {
		if(isAllAnnoSelected()) return null;
		
		String [] retVal = new String[getNumAnnoSelected()];
		
		int index=0;
		for(int x=0; x<chkAnnoDB.length; x++)
			if(chkAnnoDB[x].isSelected())
				retVal[index++] = chkAnnoDB[x].getText();
		return retVal;
	}
	
	private String [] getSelectedAnnoDBTaxos() {
		if(isAllAnnoSelected()) return null;
		
		String [] retVal = new String[getNumAnnoSelected()];
		
		int index=0;
		for(int x=0; x<chkAnnoDB.length; x++)
			if(chkAnnoDB[x].isSelected())
				retVal[index++] = lblTaxoDB[x].getText();
		return retVal;
	}
	/**
	 * Cleanup memory and garbage collect on exit of the tab
	 */
	public void close()
	{
		if(theQuery != null) theQuery.clear();
		tempContigFilter = null;
		defaultLabelDims = null;
		defaultLabelNumDims = null;
		contigNode = null;
		pairNode = null;
		uniprotPanel = null;
		selLibraryPanel = null;
		similarityPanel = null;
		contigPanel = null;
		SNPandORFPanel = null;
		GOPanel = null;
	}

	private SessionData theAssemblies = null;
	private int nChildren = 0;
	private QueryData theQuery = null;
	private FilterContigData tempContigFilter = null;
	private Dimension defaultLabelDims = null;
	private Dimension defaultLabelNumDims = null;
	
	private MenuTreeNode contigNode = null;
	private MenuTreeNode pairNode = null;

	private JLabel lblTitle = null;
	private JTextArea txtDesc = null;
	private JComponent uniprotPanel, selLibraryPanel, 
		similarityPanel, contigPanel, SNPandORFPanel, PValPanel, GOPanel;

	// Layout "constants"
	private static final int SUBGROUP_INSET_WIDTH = 50;
	private int MIN_ROW_HEIGHT = 50; 
	
	final public static int QUERY_LIST_INDIVIDUALLY = 1; 
	final public static int QUERY_LIST_CLUSTERS = 2;
	final public static int QUERY_SHOW_COUNT = 3; 
	
	// Error handling
	private JLabel lblError = new JLabel ( " " );
	private JComponent failure = null;
	private JComponent centerPanel = null;
	private JScrollPane scroller = null;
	
	private JCheckBox [] chkIncludeLibs = null;
	private JTextField [] txtIncBoolState = null;
	private JLabel [] labelIncLibs = null;
	private JCheckBox [] chkExcludeLibs = null;
	private JTextField [] txtExBoolState = null;
	private JLabel [] labelExLibs = null;
	private JCheckBox libSelAll = null;
	private JCheckBox libCheckUnChecked = null;
	
	private IncludeExcludeWidget cmbIncludeExcludeNs = null;
	private ToggleTextComboField chkNumAligns = null;
	private ToggleTextComboField chkCtgLength = null;
	private ToggleTextComboField chkTotalExpLevel = null;
	private ToggleTextField chkLessEqualSNPs = null;		
	private ToggleTextField chkGreaterEqualSNPs = null;	
	private JRadioButton chkAbsoluteLibraryCounts = null;
	private JRadioButton chkNormalizedLibraryCounts = null;
	private LibraryPromptField incLibraryCountPromptField = null, exLibraryCountPromptField = null;
	private LibraryPromptField libraryComparePromptField = null;
	private IncludeExcludeWidget cmbIncludeExcludeNotes = null;
	
	//PVal controls
	private JTextField txtPVal = null;
	private JCheckBox chkFilterPVal = null;
	private JComboBox cmbBoolPVal = null;
	private JCheckBox [] colSelectPVal = null;
	private JRadioButton[] colUpOnly = null;
	private JRadioButton[] colDownOnly = null;
	private JRadioButton[] colUpDown = null;
	private JLabel[] colpValTitle = null;

	// Anno DB widgets
	private JLabel [] lblTaxoDB = null;
	private JCheckBox [] chkAnnoDB = null;
	private JCheckBox chkAnnoDBSelAll = null;
	
	// Good UTRs widgets
	private ToggleTextField chkHasORF = null;
	private JCheckBox chkHasBothUTRs = null;
	private JCheckBox chkHasProteinORF = null;
	
	// Search 
	private ToggleTextField chkGOID = null;
	
	// Good UniProt hit widgets
	private IncludeExcludeWidget cmbFirstBest = null;
	private IncludeExcludeWidget cmbDBHitAndOr = null;
	private ToggleTextComboField chkDBHitLen = null;
	private ToggleTextComboField chkDBHitBitScore = null;
	private ToggleTextComboField chkDBHitEVal = null;
	private ToggleTextComboField chkDBHitIdent = null;
	private JRadioButton chkHasBestDBHit = null;
	private JRadioButton chkNoAnno = null;
	private JRadioButton chkEitherAnno = null;
	
	// Similarity widgets
	private JCheckBox chkPairsCutoffs = null;
	private JTextField fldPairsHSRMinNTLen = null;
	private JTextField fldPairsHSRMinNTPercentLen = null;
	private JTextField fldPairsHSRMinAALen = null;
	private JTextField fldPairsHSRMinAAPercentLen = null;
	
	private JTextField fldPairsOLPMinNTLen = null;
	private JTextField fldPairsOLPMinNTPercentLen = null;
	private JTextField fldPairsOLPMinAALen = null;
	private JTextField fldPairsOLPMinAAPercentLen = null;
	private JTextField fldPairsOLPMinAAPercentID = null;
	private JTextField fldPairsOLPMinNTPercentID = null;
	private JTextField fldPairsHSRMinAAPercentID = null;
	private JTextField fldPairsHSRMinNTPercentID = null;

	private JCheckBox chkPairsCompareBestHit = null;
	
	private JRadioButton chkUpOnlyAll; 
	private JRadioButton chkDownOnlyAll; 
	private JRadioButton chkUpDownAll; 
	private JCheckBox chkAllPVal;
	//Hold unitrans set names (name retrieval only, not filtered)
	private String [] ctgSetNameList = null;
	private String [] pValColumns = null;
	private String [] pValTitles = null;
	private String [] libColumns = null;
	private String [] libTitles = null;
	
	private static final String [] BOOLEAN_LABELS = { "<=", ">=" };
	//Labels
	public static final String GENERAL_HEADER = "General";
	public static final String GENERAL_DESCRIPTION = "Find sequences with the specified attributes.";
	public static final String LIBRARY_HEADER = "Libraries";
	public static final String LIBRARY_DESCRIPTION = "Filter sequences based on the counts or RPKM of the libraries";
	public static final String BEST_DB_HIT_HEADER = "Best Hit";
	public static final String BEST_DB_HIT_DESCRIPTION = "Search on the Best Eval and Best Anno for a sequence.";
	public static final String SPECIES_HEADER = "Species";
	public static final String SPECIES_DESCRIPTION = "Search for sequences with hits from one or more specific species";
	public static final String SNP_ORF_HEADER = "SNPs and ORFs";
	public static final String SNP_ORF_DESCRIPTION = "Find contigs with specific SNP (assembled contigs only) and/or ORF attributes.";
	public static final String GO_HEADER = "GO";
	public static final String GO_DESCRIPTION = "Search for a specific GO ID";
	public static final String PVAL_HEADER = "Differential Expression";
	public static final String PVAL_DESCRIPTION = "Filter on DE p-value columns";

	private static final int NUM_COLUMNS_ANNO = 3;
	private static final int COLUMN_WIDTH_ANNO = 150;
    private static final long serialVersionUID = 1;
}
